import 'dart:async';

import 'package:fluent_ui/fluent_ui.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:simu_studio/app/data/models/home/environment_config.dart';
import 'package:simu_studio/app/data/protocol/simu_message.pb.dart';
import 'package:simu_studio/app/modules/home/views/home_devices.dart';
import 'package:simu_studio/app/modules/home/views/home_setting.dart';
import 'package:simu_studio/app/services/influx_db_client_service.dart';
import 'package:simu_studio/app/services/mqtt_client_service.dart';

/// 设备图表显示的控制对象
class DeviceChartController {
  /// 设备名称
  late String deviceName;

  /// 图表显示的传感器集合
  late Set<String> showSensors;

  /// 图表隐藏的传感器集合
  late Set<String> hideSensors;

  /// 当前设备数据的图表是否实时刷新
  late bool realTimeUpdate;

  /// 当前设备每个传感器显示的数据量大小
  late int sensorDataSize;

  DeviceChartController({required this.deviceName}) {
    showSensors = {};
    hideSensors = {};
    realTimeUpdate = true;
    sensorDataSize = 1000;
  }

  /// 获取所有的传感器列表
  List<String> getAllSensors(){
    var result = showSensors.toList();
    result.addAll(hideSensors.toList());
    return result;
  }
}

class HomeController extends GetxController {
  /// 主界面左侧的导航窗口的索引值
  final selectIndex = 0.obs;

  /// 采集设备信息页的tabview的索引值
  var deviceTabIndex = 0.obs;

  /// 标识环境信息配置是否校验通过
  var verifyStatus = false.obs;

  /// 主界面左侧的导航窗口描述信息
  RxList<NavigationPaneItem> paneItems = RxList<NavigationPaneItem>();

  /// 接收到的所有设备数据
  /// 外层的map的key代表设备名称
  /// 内层的map的key代表传感器的名称
  Map<String, Map<String, List<SimuData>>> dataMap =
      <String, Map<String, List<SimuData>>>{}.obs;

  /// 接收到数据的设备列表
  List<String> avaliableDevices = <String>[].obs;

  /// 设备控制器列表
  List<DeviceChartController> deviceControllerList = [];

  /// 消息队列配置
  late MQConfig mqConfig;

  /// 数据库配置
  late DBConfig dbConfig;

  /// 异步流的订阅对象，当前controller销毁时需要关闭订阅流
  late StreamSubscription<SimuMessage> subscription;

  @override
  void onInit() {
    /// 初始化MQ配置参数
    _initMQConfig();

    /// 初始化DB参数
    _initDBConfig();

    /// 初始化左侧导航页
    paneItems.value = [
      PaneItem(
        icon: const Icon(FluentIcons.settings),
        key: const ValueKey('/home/setting'),
        body: HomeSettingView(),
        title: Text('Home_Setting'.tr),
      ),
      PaneItem(
        icon: const Icon(FluentIcons.chart),
        key: const ValueKey('/home/devices'),
        body: HomeDevicesView(),
        title: Text('Home_AllDevices'.tr),
      ),
      // PaneItem(
      //   icon: const Icon(FluentIcons.b_i_dashboard),
      //   key: const ValueKey('home/datacheck'),
      //   body: Container(),
      //   title: Text('Home_DataCheck'.tr),
      // )
    ];
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
  }

  @override
  void onClose() {
    super.onClose();
    /// 关闭异步流的订阅
    subscription.cancel();
  }

  /// 设置导航页的item索引
  void setSelectedIndex(int index) {
    selectIndex.value = index;
  }

  /// 初始化MQ配置，默认从缓存中读取，如果缓存中没有则使用默认值
  void _initMQConfig() {
    GetStorage box = GetStorage();
    mqConfig = MQConfig(
        serverIP: box.read('mq_server_ip') ?? "localhost",
        serverPort: box.read("mq_server_port") ?? 1883,
        subscriptions: box.read("mt_subscriptions") ?? "device");
  }

  /// 初始化InfluxDB配置，默认从缓存中读取，如果缓存中没有则使用默认值
  void _initDBConfig() {
    GetStorage box = GetStorage();
    dbConfig = DBConfig(
        serverIP: box.read('db_server_ip') ?? 'localhost',
        port: box.read('db_server_port') ?? 8086,
        organizationName: box.read('db_organization_name') ?? 'keliang',
        token: box.read('db_token') ?? '',
        bucket: box.read('db_bucket') ?? 'device_receive',
        batchSize: box.read('db_batch_size') ?? 100);
  }

  /// 根据配置参数连接到MQ服务
  Future<bool> connectToMQ() async {
    MqttClientService clientService = Get.find();
    if (clientService.isConnected()) {
      return true;
    }
    bool isSucceed =
        await clientService.connectToServer(mqConfig.serverIP, "display1");
    if (!isSucceed) {
      return false;
    }
    isSucceed = clientService.subscribe(mqConfig.subscriptions, 0);
    if (!isSucceed) {
      return false;
    }
    verifyStatus.value = true;
    selectIndex.value = 1;
    subscription =
        clientService.messageStream.stream.listen(onReceiveSimuMessage);
    return true;
  }

  /// 根据配置参数连接到InfluxDB数据库
  /// 构建了一个http请求的对象
  /// 此接口总是返回true，因为暂时没有提供连接成功的接口
  bool connectToDB() {
    InfluxDBClientService dbClientService = Get.find();
    var url = "http://${dbConfig.serverIP}:${dbConfig.port}";
    return dbClientService.connectToDB(url, dbConfig.token,
        dbConfig.organizationName, dbConfig.bucket, dbConfig.batchSize);
  }

  /// 接收MQ消息接收到的消息流
  void onReceiveSimuMessage(SimuMessage message) {
    // 获取设备的控制器对象
    DeviceChartController deviceController = deviceControllerList.firstWhere(
        (element) => element.deviceName == message.name,
        orElse: () => DeviceChartController(deviceName: ''));
    for (var data in message.datas) {
      String sensorName = data.id.toString();
      if (dataMap.containsKey(message.name)) {
        dataMap[message.name]?.update(sensorName, (value) {
          if (deviceController.deviceName == message.name) {
            bool newSensor =
                !deviceController.showSensors.contains(sensorName) &&
                    !deviceController.hideSensors.contains(sensorName);
            if (newSensor) {
              // 把新的传感器对象添加到需要显示的设备传感器列表中
              deviceController.showSensors.add(sensorName);
            }
          }
          /// 缓存的数据不超过设置的传感器显示的数据量大小
          if (value.length > deviceController.sensorDataSize) {
            value.removeRange(0, value.length - deviceController.sensorDataSize);
          }
          value.add(data);
          return value;
        }, ifAbsent: () => <SimuData>[data]);
      } else {
        Map<String, List<SimuData>> deviceMap = {};
        deviceMap[sensorName] = <SimuData>[data];
        dataMap[message.name] = deviceMap;
        // 添加可用设备列表
        avaliableDevices.add(message.name);
        deviceController = DeviceChartController(deviceName: message.name);
        deviceController.showSensors.add(data.id.toString());
        deviceControllerList.add(deviceController);
      }
    }
    // 刷新当前设备的图表
    if(deviceController.deviceName == message.name){
      if(deviceController.realTimeUpdate){
        // 如果需要实时更新，那么就刷新图表数据
        update([message.name]);
      }
    }else{
      update([message.name]);
    }
  }

  /// 根据设备名称获取传感器数据列表，用来给图表显示
  List<SimuData> getSimuDataList(String deviceName) {
    List<SimuData> data = [];
    if (!dataMap.containsKey(deviceName)) {
      return data;
    } else {
      DeviceChartController deviceController = deviceControllerList.firstWhere(
              (element) => element.deviceName == deviceName,
          orElse: () => DeviceChartController(deviceName: ''));
      var deviceDatas = dataMap[deviceName];
      deviceDatas?.forEach((key, value) {
        if(deviceController.deviceName == deviceName && deviceController.hideSensors.contains(key)){
          return;
        }
        if(value.length > deviceController.sensorDataSize){
          data.addAll(value.getRange(value.length-deviceController.sensorDataSize, value.length));
          return;
        }
        data.addAll(value);
      });
    }
    return data;
  }

  /// 根据设备名称获取图表的显示控制器
  DeviceChartController getDeviceController(String deviceName){
    return deviceControllerList.firstWhere(
            (element) => element.deviceName == deviceName,
        orElse: () => DeviceChartController(deviceName: ''));
  }

  /// 控制传感器数据显示隐藏
  /// deviceName:设备名称
  /// sensorName:传感器名称
  /// checked:是否显示
  String deviceSensorCheckChanged(String deviceName,String sensorName,bool checked){
    DeviceChartController deviceController = getDeviceController(deviceName);
    if(deviceController.deviceName != deviceName){
      return '';
    }
    if(checked){
      deviceController.showSensors.add(sensorName);
      deviceController.hideSensors.remove(sensorName);
    }else{
      if(deviceController.showSensors.length == 1){
        // 图表数据不能为空
        return 'Home_Text_ChartDataShouldNotBeEmpty'.tr;
      }
      deviceController.hideSensors.add(sensorName);
      deviceController.showSensors.remove(sensorName);
    }
    update([deviceName]);
    return '';
  }

  /// 设置设备传感器的显示数据量大小
  /// deviceName:设备名称
  /// size:显示数据量大小
  void setDeviceSensorSize(String deviceName,int size){
    DeviceChartController deviceController = getDeviceController(deviceName);
    if(deviceController.deviceName != deviceName){
      return ;
    }
    deviceController.sensorDataSize = size;
    update([deviceName]);
  }

  /// 设置设备是否实时刷新图表
  /// deviceName:设备名称
  /// value:true表示实时显示刷新，false表示不刷新
  void setDeviceRealUpdate(String deviceName,bool value){
    DeviceChartController deviceController = getDeviceController(deviceName);
    if(deviceController.deviceName != deviceName){
      return ;
    }
    deviceController.realTimeUpdate = value;
    update([deviceName]);

  }

}
